﻿using GalaSoft.MvvmLight.Command;
using JiveMessenger.Converters;
using JiveMessenger.Models;
using JiveMessenger.Utilities;
using JiveMessenger.ViewModels;
using JmShared;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace JiveMessenger.SampleData
{
    class SampleViewModelContactList : IViewModelContactList
    {
        public RelayCommand<IContact> AddContactCommand { get; set; }
        public RelayCommand OpenAddContactWindowCommand { get; set; }
        public RelayCommand OpenCreateGroupWindowCommand { get; set; }
        public RelayCommand<object> InviteContactToGroupCommand { get; set; }
        public RelayCommand<object> LeaveGroupCommand { get; set; }
        public RelayCommand<object> BlockGroupCommand { get; set; }
        public RelayCommand<IContact> OpenPmCommand { get; set; }
        public RelayCommand OpenNotificationsCommand { get; set; }
        public RelayCommand<IContact> IgnoreContactCommand { get; set; }
        public RelayCommand<IChatGroup> OpenGroupCommand { get; set; }
        public RelayCommand<IChatGroup> ManageGroupCommand { get; set; }
        public RelayCommand<IChatGroup> SetGroupExpandedCommand { get; set; }
        public RelayCommand<IChatGroup> SetGroupCollapsedCommand { get; set; }
        public SampleViewModelContactList()
        {
            RunOnNetworkConnect();
        }

        public void Cleanup()
        {

        }


        private CollectionViewSource _contactsViewSource;
        public CollectionViewSource ContactsViewSource
        {
            get { return _contactsViewSource; }
            set
            {
                _contactsViewSource = value;
            }
        }
        private FilteredObservableCollection<IContact> _contacts;
        public FilteredObservableCollection<IContact> Contacts
        {
            get
            {
                if (_contacts == null)
                {
                    System.Collections.ObjectModel.ObservableCollection<IContact> samples = new System.Collections.ObjectModel.ObservableCollection<IContact>();
                    Random rand = new Random((int)DateTime.Now.Ticks);
                    string[] usernames = new string[] { "ole.skodje@gmail.com", "foo@bar.com", "testuser@testdomain.com", "trololo@tralala.com", "larsolav@gmail.com", "heihei@test.com", "lorem@ipsum.com" };
                    string[] ids = new string[] { "#pc1234", "#wp1234", "#pc2345", "#wp2345", "#pc3456", "#pc54555", "#android1234", "#android2345", "#android3456" };
                    string[] nicknames = new string[] { "long,long,long nick", "this is a very long nick", "sverre", "ole", "lars", "stian", "this is an even longer nick then before" };
                    SolidColorBrush[] colors = new SolidColorBrush[] { Brushes.Red, Brushes.Black, Brushes.Blue, Brushes.Yellow, Brushes.Violet, Brushes.Fuchsia };
                    Dictionary<int, string> chatGroups = new Dictionary<int, string>();
                    for (int i = 0; i < rand.Next(3, 6); i++)
                    {
                        chatGroups.Add(i, string.Format("Group {0}", i));
                    }

                    int clientNum = rand.Next(3, 10);
                    for (int i = 0; i < clientNum; i++)
                    {
                        string username = usernames[rand.Next(0, usernames.Length)];
                        string userID = username + ids[rand.Next(0, ids.Length)];
                        JmShared.ClientStatus clientStatus = JmShared.ClientStatus.Available;
                        JmShared.DeviceType deviceType = JmShared.DeviceType.PC;
                        int status = rand.Next(1, 5);
                        if (status == 1)
                        {
                            clientStatus = JmShared.ClientStatus.Afk;
                            deviceType = JmShared.DeviceType.PC;
                        }
                        else if (status == 2)
                        {
                            clientStatus = JmShared.ClientStatus.Available;
                            deviceType = JmShared.DeviceType.Android;
                        }
                        else if (status == 3)
                        {
                            clientStatus = JmShared.ClientStatus.Busy;
                            deviceType = JmShared.DeviceType.WindowsPhone;
                        }
                        else if (status == 4)
                            clientStatus = JmShared.ClientStatus.Offline;
                        List<IChatGroup> userGroups = new List<IChatGroup>();

                        int max = rand.Next(1, 3);
                        for (int n = 0; n < max; n++)
                        {
                            var value = chatGroups.ElementAt(rand.Next(0, chatGroups.Count));
                            Dictionary<string, GroupPrivilege> groupMembers = new Dictionary<string, GroupPrivilege>();
                            groupMembers.Add(username, GroupPrivilege.Owner);
                            for (int r = 0; r < max; r++)
                            {
                                string user = usernames[rand.Next(0, usernames.Length)];
                                if (!groupMembers.ContainsKey(user))
                                    groupMembers.Add(user, GroupPrivilege.Member);
                            }

                            if (!userGroups.Any(x => x.ID == value.Key.ToString()))
                                userGroups.Add(new JiveChatGroupModel(value.Key.ToString(), value.Value, groupMembers) { IsBlocked = rand.Next(1, 100) > 50 ? true : false, IsExpanded=true });
                        }

                        samples.Add(new Models.JiveContactModel("1", userID, nicknames[rand.Next(0, nicknames.Length)] + " (" + i + ")", DeviceType.PC)
                        {
                            AfkStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, rand.Next(0, 4), rand.Next(0, 60), rand.Next(0, 60)),
                            UnreadMessageCount = rand.Next(0, 20),
                            ClientStatus = clientStatus,
                            ChatGroups = new ObservableCollection<IChatGroup>(userGroups),
                            DeviceType = deviceType,
                            IsIgnored = rand.Next(0, 100) >= 50,
                            Avatar = new BitmapImage(new Uri("/JiveMessenger;component/Resources/Images/avatar_empty.png", UriKind.Relative)),
                            FontColor = colors[rand.Next(0, 6)]

                        });

                    }

                    _contacts = new FilteredObservableCollection<IContact>(samples.OrderBy(x =>
                        {
                            if (x.ClientStatus == JmShared.ClientStatus.Offline)
                                return 1;
                            else
                                return 0;
                        }));
                    this.CurrentUser = _contacts[0];
                }

                return _contacts;
            }
            set
            {

            }
        }

        public void SetContactAsOffline(string userName)
        {
            throw new NotImplementedException();
        }


        public void RunOnNetworkConnect()
        {
            Contacts = new FilteredObservableCollection<IContact>();
            CollectionViewSource src = new CollectionViewSource();
            src.Source = Contacts;
            var locator = (ViewModelLocator)Application.Current.Resources["Locator"];
            var onlineGroup = new JiveClientStatusGroupModel("JiveClientStatusGroupOnline",JiveStatusGroupStatus.Online);
            var offlineGroup = new JiveClientStatusGroupModel("JiveClientStatusGroupOffline",JiveStatusGroupStatus.Offline);
            offlineGroup.IsExpanded = true;
            onlineGroup.IsExpanded = true;
            var groupDescription = new PropertyGroupDescription("ClientStatus", new ContactGroupStatusConverter() { OfflineGroup = offlineGroup, OnlineGroup = onlineGroup });

            src.GroupDescriptions.Add(groupDescription);
            JiveFriendsGroupModel friendsGroup = new JiveFriendsGroupModel("JiveFriendsGroup");
            JiveFriendsGroupModel offlineFriendsGroup = new JiveFriendsGroupModel("OfflineJiveFriendsGroup");

            groupDescription = new PropertyGroupDescription("Instance", new ContactChatGroupConverter() { ContactModels = Contacts, CurrentClient = this.CurrentUser, FriendsGroup= friendsGroup, OfflineFriendsGroup = offlineFriendsGroup });


            // this foreach must at least add clusters that can't be
            // derived from items - i.e. groups with no items in them

            foreach (var grp in CurrentUser.ChatGroups)
                groupDescription.GroupNames.Add(grp);

            src.GroupDescriptions.Add(groupDescription);
            src.Filter += (s, args) =>
            {
                IContact model = (IContact)args.Item;
                if (model.UserID == CurrentUser.UserID)
                    args.Accepted = false;
                else
                    args.Accepted = true;
            };
            this.ContactsViewSource = src;
        }

        private IContact _currentUser;
        public IContact CurrentUser
        {
            get
            {
                return _currentUser;
            }
            set
            {
                _currentUser = value;
            }
        }




        public void RunOnNetworkDisconnect()
        {

        }


        public ClientStatus ManualClientStatus
        {
            get
            {
                return ClientStatus.Afk;
            }
            set
            {
                throw new NotImplementedException();
            }
        }


        public void AddOrUpdateContact(UserInfo user, bool processEmoticonAndAvatar)
        {
            throw new NotImplementedException();
        }
    }
}
